package com.thoughtservice.jspdoc.processors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.thoughtservice.jspdoc.JSPFileList;
import com.thoughtservice.jspdoc.JSPPage;
import com.thoughtservice.jspdoc.RE;
import com.thoughtservice.jspdoc.RESyntaxException;

public class ProcessAllParams implements DocProcessor{
	
	private final static Logger LOG = LoggerFactory.getLogger(ProcessAllParams.class);	


	/**
	 * Try to extract the documentation about a single parameter from the comments above
	 * the parameter.  This looks for comments of the following form:
	 * <pre>
	 *  /**
	 *   * [parameterName]
	 *   * type: [parameterType]
	 *   * desc: [description of the parameter
	 *   *\/
	 *  [Code to get the parameter from the request]
	 * </pre>
	 * 
	 * @param param java.lang.String The name of the parameter to look for documentation for
	 * @param p ca.yourdecor.jspdoc.JSPPage The page we're documenting
	 * @param pc java.lang.String The source code of the jsp page
	 */
	private void processParam(String param, JSPPage p, String pc, String source) throws RESyntaxException {
		LOG.trace("Entering {}", "processParam");
//if (param.startsWith("forceHeader"))
//	System.out.println("hello");
		//System.out.println("\t\t" + param);	
		//	RE re = new RE("<%[:print:]*/\\*\\*[:space:]*\\*[:space:]*" + param + "[:print:]*\\*//");
		//	RE re = new RE("[:space:]*/\\*\\*[:space:]*\\*[:space:]*" + param + "[:print:]*\\*//");
		//	RE re = new RE("/\\*\\*[:blank:]*\\*[:blank:]*" + param + "[:print:]*\\*//");
		//	RE re = new RE("/\\*\\*[:blank:]*\\*[:blank:]*" + param);
		//	RE re = new RE("/\\*\\*[:space:]*\\*");
		//	RE re = new RE("/\\*\\*[:space:]*\\*[:space:]*" + param + "[:space:]*[:print:]*\\*/");
		RE re = new RE("/\\*\\*[:space:]*\\*[:space:]*" + param + ".*?\\*/");
		re.match(pc);
		String doc = re.getParen(0);
		if (doc != null) {
			//System.out.println(doc); 
			re = new RE("\\*[:space:]type:[:space:]*(.*)\\*[:space:]*desc:[:space:]*(.*)\\*/");
			re.match(doc);
			String type = re.getParen(1);
			String desc = re.getParen(2);
			if (type == null)
				type = "";
			if (desc == null)
				desc = "";
			desc = desc.replace('*', ' ');

			//System.out.println(type);
			//System.out.println(desc);
			p.addParameter(param, type, desc, source);
		} else {
			p.addParameter(param, p.TYPEUNKNOWN, "not documented", source);
		}
		LOG.trace("Exiting {}", "processParam");
	}




	/**
	 * Look for parameters used on this JSPPage.  This will look for the
	 * following forms of Parameters:
	 * <pre>
	 *  request.getParameter("[someParameterName]");
	 *  Utils.getValue(h, "[someParameterName]");
	 *  Utils.getIntValue(h, "[someParameterName]");
	 * </pre>
	 * This should be improved to capture more forms.
	 * 
	 * @param p ca.yourdecor.jspdoc.JSPPage The page to look for parameters in
	 * @param pc java.lang.String The contents of the page (the source code)
	 */
	public boolean process(JSPPage p, String pc, JSPFileList fileList) throws RESyntaxException {

		LOG.trace("Entering {}", "ProcessAllParams");
//		System.out.println("\t\ta");
		// Look for the request.getParameter("...") type of parameters	 	
		RE re = new RE("request.getParameter\\([:space:]*\"[:print:]*?\"\\)");
		int index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCEPARAMETER);
		}

		// Look for the request.getParameterValues("...") type of parameters            
		re = new RE("request.getParameterValues\\([:space:]*\"[:print:]*?\"\\)");
		index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCEPARAMETER);
		}

//		System.out.println("\t\tb");
		// Look for the Utils.getValue(h, "...") type of parameters
		re = new RE("Utils\\.getValue\\(h,[:space:]*\"[:print:]*?\"\\)");
		index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
//System.out.println(param);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCEPARAMETER);
		}

//		System.out.println("\t\tc");

		// Look for the Utils.getIntValue(h, "...") type of parameters
		re = new RE("Utils\\.getIntValue\\(h,[:space:]*\"[:print:]*?\"\\)");
		index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCEPARAMETER);
		}


		// Look for session parameters session.getAttribute("...") 
		re = new RE("session\\.getAttribute\\([:space:]*\"[:print:]*?\"[:space:]*\\)");
		index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCESESSION);
		}



		// Look for session parameters request.getSession().getAttribute("...") 
		re = new RE("request\\.getSession\\.getAttribute\\([:space:]*\"[:print:]*?\"[:space:]*\\)");
		index = 0;
		while (re.match(pc, index)) {
			String param = re.getParen(0);
			index = re.getParenEnd(0);
			RE re2 = new RE("\"\\S*\"");
			re2.match(param);
			param = re2.getParen(0);
			param = param.substring(1, param.length() - 1);
			processParam(param, p, pc, p.SOURCESESSION);
		}
		LOG.trace("Exxiting {}", "ProcessAllParams");
		return true;
	}


}
